home *** CD-ROM | disk | FTP | other *** search
/ JCSM Shareware Collection 1993 November / JCSM Shareware Collection - 1993-11.iso / cl720 / sst115j.lzh / SSTFLD.C < prev    next >
C/C++ Source or Header  |  1992-07-18  |  20KB  |  710 lines

  1. /* ------------------------------------------------------------------------ */
  2. /*                                sstfield.c                                */
  3. /*                    high-level formatted input routines                   */
  4. /*                                                                          */
  5. /*      CopyRight (C) 1991,1992  Steven Lutrov.   All rights reserved.      */
  6. /* ------------------------------------------------------------------------ */
  7. #include <stdio.h>
  8. #include <ctype.h>
  9. #include <stdlib.h>
  10. #include <alloc.h>
  11. #include <mem.h>
  12. #include <string.h>
  13. #include <conio.h>
  14.  
  15. #include "sstvid.h"
  16. #include "sstwin.h"
  17. #include "sstkey.h"
  18. #include "ssthlp.h"
  19.  
  20. #define  _isalpha(c)   (isalpha(c) || isspace(c))
  21. #define  _isalnum(c)   (isalnum(c) || isspace(c))
  22.  
  23. /* ------------------------------------------------------------------------ */
  24. /*                             local prototypes                             */
  25. /* ------------------------------------------------------------------------ */
  26. static void  addfield           (WINDOW *wnd, FIELD *fld);
  27. static void  dispfield          (WINDOW *wnd, char *bf, char *msk);
  28. static void  datavalue          (WINDOW *wnd, FIELD *fld, int n);
  29. static void  postprocess        (FIELD *fld);
  30. static void  preprocess         (FIELD *fld, int *c, int p);
  31. static void  insertstatus       (void);
  32. static int   readfield          (WINDOW *wnd, FIELD *fld);
  33. static void  rjust              (char *s);
  34. static void  rjustzf            (char *s);
  35. static int   esdefault          (int c);
  36. static int   spaces             (char *c);
  37. static int   testftype          (FIELD *fld, int c);
  38. static void  processhelp        (FIELD *fld);
  39. static int   esinputline        (int c);
  40. static void  deferrorfunc       (char *s);
  41.  
  42.  
  43. int    insertmode = FALSE;                /* insert mode, TRUE/FALSE */
  44. int    (*fend) (int) = esdefault;           /* field end keystroke func */
  45. extern int helpkey;                         /* key to activate help */
  46.  
  47. /* ------------------------------------------------------------------------ */
  48. /*                          initialize a template                           */
  49. /* ------------------------------------------------------------------------ */
  50. void Finittemplate(WINDOW *wnd)
  51. {
  52.     FIELD *fld, *fl;
  53.  
  54.     fld = FHEAD;
  55.     while (fld)    {
  56.         fl = fld->fnxt;
  57.         free(fld);
  58.         fld = fl;
  59.     }
  60.     FHEAD = NULL;
  61. }
  62.  
  63. /* ------------------------------------------------------------------------ */
  64. /*                    establish a field in a template                       */
  65. /* ------------------------------------------------------------------------ */
  66. FIELD *Festablish(WINDOW *wnd, int cl, int rw, char *msk,
  67.               char *bf, int ty, int flags)
  68. {
  69.     FIELD *fld;
  70.  
  71.     if ( (fld = malloc(sizeof(FIELD))) == NULL)
  72.         return NULL;
  73.     fld->fmask = msk;
  74.     fld->frow = rw;
  75.     fld->fcol = cl;
  76.     fld->fbuff = bf;
  77.     fld->ftype = ty;
  78.     fld->fprot = 0;
  79.     fld->fnxt = fld->fprv = NULL;
  80.     fld->fvalid = NULL;
  81.     fld->ferror = deferrorfunc;
  82.     fld->fvalid = NULL;
  83.     fld->helptype = HELP_KEYED;
  84.     fld->fhwin = NULL;
  85.     fld->fprevalid = NULL;
  86.     fld->flx = fld->fly = 0;
  87.     fld->fflags = flags;
  88.     addfield(wnd, fld);
  89.     return fld;
  90. }
  91.  
  92. /* ------------------------------------------------------------------------ */
  93. /*                  creates a single input line in a window                 */
  94. /* ------------------------------------------------------------------------ */
  95. char *Finputline(char *p, char *bf, int x, int y, int l, int t)
  96.  
  97. {
  98.     WINDOW *wnd;
  99.     char *msk, *buf;
  100.     int c;
  101.  
  102.     if ((msk = malloc(l)) == NULL)
  103.     return (NULL);
  104.     if ((buf = malloc(l)) == NULL)
  105.     return (NULL);
  106.     memset(msk,'_',l);
  107.     memset(buf,32,l);
  108.     msk[l-1] = '\x0';
  109.     memcpy(buf,bf,l);
  110.     if ((wnd = Westablish(x, y, 3, strlen(p)+l+4)) == NULL)
  111.     return (NULL);
  112.     Wsetcolour(wnd, WIN_BORDER,  LIGHTGRAY, WHITE, BRIGHT);
  113.     Wsetcolour(wnd, WIN_TITLE,   LIGHTGRAY, RED, DIM);
  114.     Wsetcolour(wnd, WIN_FACE,    LIGHTGRAY, BLACK, DIM);
  115.     Wsetcolour(wnd, WIN_ACCENT,  GREEN,     BLACK, DIM);
  116.     Wsetcolour(wnd, WIN_FLDFACE, LIGHTGRAY, RED,  DIM);
  117.     Wsettitle(wnd, "[Input line]",JUST_L);
  118.     Wshow(wnd);
  119.     Wprompt(wnd,0,0, p);
  120.  
  121.     Finittemplate(wnd);
  122.     Festablish(wnd, strlen(p)+2,0, msk, buf, t,0);
  123.     Fendfunc(esinputline);
  124.     c = Fdataentry(wnd,1);
  125.     Fendfunc(NULL);
  126.     buf[l-1] = '\x0';
  127.     Wdelete(wnd);
  128.     return (c == ENTER ? buf : bf);
  129. }
  130.  
  131. /* ------------------------------------------------------------------------ */
  132. /*                   display all the fields in a window                     */
  133. /* ------------------------------------------------------------------------ */
  134. void Ftally(WINDOW *wnd)
  135. {
  136.     FIELD *fld;
  137.  
  138.     fld = FHEAD;
  139.     while (fld != NULL)    {
  140.         datavalue(wnd, fld,WFIELD);
  141.         fld = fld->fnxt;
  142.     }
  143. }
  144.  
  145. /* ------------------------------------------------------------------------ */
  146. /*                      set a field's help window                           */
  147. /* ------------------------------------------------------------------------ */
  148. void Fsethelpwin(FIELD *fld, char *hwin, int x, int y)
  149. {
  150.     fld->fhwin=hwin;
  151.     fld->flx = x;
  152.     fld->fly = y;
  153. }
  154.  
  155. /* ------------------------------------------------------------------------ */
  156. /*                      clear a template to all blanks                      */
  157. /* ------------------------------------------------------------------------ */
  158. void Fcleartemplate(WINDOW *wnd)
  159. {
  160.     FIELD *fld;
  161.     char *bf, *msk;
  162.  
  163.     fld = FHEAD;
  164.     while (fld != NULL)    {
  165.         bf = fld->fbuff;
  166.         msk = fld->fmask;
  167.         while (*msk)    {
  168.             if (*msk == FIELDCHAR)
  169.                 *bf++ = ' ';
  170.             msk++;
  171.         }
  172.         fld = fld->fnxt;
  173.     }
  174.     Ftally(wnd);
  175. }
  176.  
  177. /* ------------------------------------------------------------------------ */
  178. /*                      clear a template to all nulls                       */
  179. /* ------------------------------------------------------------------------ */
  180. void Fnulltemplate(WINDOW *wnd)
  181. {
  182.     FIELD *fld;
  183.     char *bf, *msk;
  184.  
  185.     fld = FHEAD;
  186.     while (fld != NULL)    {
  187.         bf = fld->fbuff;
  188.         msk = fld->fmask;
  189.         while (*msk)    {
  190.             if (*msk == FIELDCHAR)
  191.                 *bf++ = 0x00;
  192.             msk++;
  193.         }
  194.         fld = fld->fnxt;
  195.     }
  196.     Ftally(wnd);
  197. }
  198.  
  199. /* ------------------------------------------------------------------------ */
  200. /*                  Process data entry for a screen template.               */
  201. /* ------------------------------------------------------------------------ */
  202. int Fdataentry(WINDOW *wnd, int p)
  203. {
  204.    FIELD *fld;
  205.    int exitcode, isvalid, dir = DOWN;
  206.    int done=FALSE;
  207.    int oldhelpkey = helpkey;
  208.  
  209.  
  210.    Ftally(wnd);
  211.    fld = FHEAD;
  212.  
  213.    /* ---- collect data from keyboard into screen ---- */
  214.  
  215.    while (fld != NULL && done == FALSE)    {
  216.     Hset(fld->fhwin, fld->flx, fld->fly);
  217.     helpkey = (fld->fhelp) ? 0 : oldhelpkey;
  218.     Wcursor(wnd, fld->fcol, fld->frow);
  219.     if (fld->fprot == FALSE)    {
  220.         Wrevvideo(wnd);
  221.         datavalue(wnd, fld,WACCENT);
  222.         Wcursor(wnd, fld->fcol, fld->frow);
  223.         exitcode = readfield(wnd, fld); /* process */
  224.         isvalid = (exitcode != ESC && fld->fvalid) ?
  225.                 (*(fld->fvalid))(fld->fbuff) : OK;
  226.     }
  227.     else    {   /* protected field */
  228.          switch (dir) {
  229.            case   DOWN  : exitcode = RIGHT;
  230.                   break;
  231.            case   UP    : exitcode = LEFT;
  232.                   break;
  233.          }
  234.          isvalid = OK;
  235.     }
  236.     if (isvalid == OK)    {
  237.        Wresetvideo(wnd);
  238.        datavalue(wnd, fld,WFIELD);
  239.        switch (exitcode)    {        /* passed edit */
  240.          case F1     : if (fld->fhelp)    {
  241.                  (*(fld->fhelp))(fld->fbuff);
  242.                  datavalue(wnd, fld,WFIELD);
  243.                  }
  244.                break;
  245.          case DOWN   :
  246.          case '\r'   :
  247.          case '\t'   :
  248.          case RIGHT  :
  249.                dir = DOWN;
  250.                if ( (exitcode == '\r')  && (p) )
  251.                 done = fend(exitcode);
  252.                else {
  253.                  fld = fld->fnxt;
  254.                  if (fld == NULL)
  255.                 fld = FHEAD;
  256.                  processhelp(fld);
  257.                }
  258.                break;
  259.          case UP     :
  260.          case LEFT   : dir = UP;
  261.                fld = fld->fprv;
  262.                if (fld == NULL)
  263.                 fld = FTAIL;
  264.                processhelp(fld);
  265.                break;
  266.          case PGUP   :
  267.          case HOME   : dir = UP;
  268.                if (p)
  269.                 done = fend(exitcode);
  270.                else {
  271.                  fld = FHEAD;
  272.                  processhelp(fld);
  273.                }
  274.                break;
  275.  
  276.          case PGDN   :
  277.          case END    : dir = DOWN;
  278.                if (p)
  279.                 done = fend(exitcode);
  280.                else {
  281.                  fld = FTAIL;
  282.                  processhelp(fld);
  283.                }
  284.                break;
  285.  
  286.          default     : done = fend(exitcode);
  287.                break;
  288.         }
  289.     }
  290.   }
  291.   helpkey = oldhelpkey;
  292.   return (exitcode);
  293. }
  294.  
  295. /* ------------------------------------------------------------------------ */
  296. /*                  View  data entry for a screen template.                 */
  297. /* ------------------------------------------------------------------------ */
  298. int Fdataview(WINDOW *wnd)
  299. {
  300.    int c;
  301.  
  302.    vhidecur();
  303.    Ftally(wnd);
  304.    c = kgetch();
  305.    vshowcur();
  306.    return (c);
  307. }
  308.  
  309. /* ------------------------------------------------------------------------ */
  310. /*                          display a window prompt                         */
  311. /* ------------------------------------------------------------------------ */
  312. void Wprompt(WINDOW *wnd, int x, int y, char *s)
  313. {
  314.     Wcursor(wnd, x, y);
  315.     Wprintf(wnd, s);
  316. }
  317.  
  318. /* ------------------------------------------------------------------------ */
  319. /*                      set the help function for a field                   */
  320. /* ------------------------------------------------------------------------ */
  321. void Fhelpfunc(FIELD *fld, void (*func)(char *), int w)
  322.  
  323. {
  324.   fld->fhelp = func;
  325.   fld->helptype = w;
  326. }
  327.  
  328. /* ------------------------------------------------------------------------ */
  329. /*                      set the error function for a field                  */
  330. /* ------------------------------------------------------------------------ */
  331. void Ferrorfunc(FIELD *fld, void (*func)(char *))
  332.  
  333. {
  334.   fld->ferror = func;
  335. }
  336.  
  337. /* ------------------------------------------------------------------------ */
  338. /*                      set the help function for a field                   */
  339. /* ------------------------------------------------------------------------ */
  340. void Fendfunc(int (*func) (int))
  341.  
  342. {
  343.   if (func)
  344.       fend = func;
  345.    else
  346.       fend = esdefault;
  347. }
  348.  
  349. /* ------------------------------------------------------------------------ */
  350. /*                   add a field to the end of the list                     */
  351. /* ------------------------------------------------------------------------ */
  352. static void addfield(WINDOW *wnd, FIELD *fld)
  353. {
  354.     if (FTAIL)    {
  355.         fld->fprv = FTAIL;
  356.         FTAIL->fnxt = fld;
  357.     }
  358.     FTAIL = fld;
  359.     if (!FHEAD)
  360.         FHEAD = fld;
  361. }
  362.  
  363. /* ------------------------------------------------------------------------ */
  364. /*                          display a data field                            */
  365. /* ------------------------------------------------------------------------ */
  366. static void dispfield(WINDOW *wnd, char *bf, char *msk)
  367. {
  368.      while (*msk)    {
  369.     Wputch(wnd, *msk != FIELDCHAR ? *msk : *bf++);
  370.     msk++;
  371.      }
  372. }
  373. /* ------------------------------------------------------------------------ */
  374. /*                          display a data field                            */
  375. /* ------------------------------------------------------------------------ */
  376. static void datavalue(WINDOW *wnd, FIELD *fld, int n)
  377. {
  378.  
  379.      char *msk = fld->fmask;
  380.      char *bf = fld->fbuff;
  381.      int x = fld->fcol+1;
  382.  
  383.      while (*msk)    {
  384.     displ(wnd, x++, fld->frow+1, *msk != FIELDCHAR ? *msk : *bf++, n);
  385.     msk++;
  386.      }
  387. }
  388.  
  389. /* ------------------------------------------------------------------------ */
  390. /*                     set insert/exchange cursor shape                     */
  391. /* ------------------------------------------------------------------------ */
  392. static void insertstatus(void)
  393. {
  394.    vsetcurtype(insertmode ? 0x0106 : 0x0607);
  395. }
  396.  
  397. /* ------------------------------------------------------------------------ */
  398. /*     process field according to flags after the field edit is complete    */
  399. /* ------------------------------------------------------------------------ */
  400. static void postprocess(FIELD *fld)
  401.  
  402. {
  403.     if (fld->fflags & FLD_ZFILL)
  404.         rjustzf(fld->fbuff);
  405.     else
  406.       if (fld->fflags & FLD_RJUST)
  407.         rjust(fld->fbuff);
  408. }
  409.  
  410. /* ------------------------------------------------------------------------ */
  411. /*          process user input according to flags as they are keyed in      */
  412. /* ------------------------------------------------------------------------ */
  413. static void preprocess(FIELD *fld, int *c, int p)
  414.  
  415. {
  416.     char *bf = fld->fbuff;
  417.  
  418.     if (fld->fprevalid != NULL)
  419.            fld->fprevalid(c);
  420.     if (fld->fflags & FLD_TOUPPER)
  421.            *c = toupper(*c);
  422.     if (fld->fflags & FLD_TOLOWER)
  423.            *c = tolower(*c);
  424.     if (fld->fflags & FLD_TOPROPER) {
  425.          if (p == fld->fcol)    /* first char in field */
  426.            *c = toupper(*c);
  427.          if (isspace( *(bf+(p-fld->fcol-1))) )
  428.            *c = toupper(*c);
  429.         }
  430. }
  431.  
  432. /* ------------------------------------------------------------------------ */
  433. /*                     read a field from the keyboard                       */
  434. /* ------------------------------------------------------------------------ */
  435. static int readfield(WINDOW *wnd, FIELD *fld)
  436. {
  437.     char *mask = fld->fmask;
  438.     char *buff = fld->fbuff;
  439.     int done = FALSE, c, column;
  440.  
  441.     column = fld->fcol;
  442.     while (*mask != FIELDCHAR)    {
  443.     column++;
  444.     mask++;
  445.     }
  446.     while (TRUE)    {
  447.     Wcursor(wnd, column, fld->frow);
  448.     c = kgetch();
  449.     if (c < 0x80)
  450.           preprocess(fld,&c,column);
  451.     (fld->ferror)(NULL); /* clear error function text */
  452.     switch (c)    {
  453.          case '\b':
  454.          case LEFT:
  455.             if (buff == fld->fbuff)    {
  456.               done = c == LEFT;
  457.               break;
  458.             }  /* left */
  459.             --buff;
  460.             do    {
  461.                 --mask;
  462.                 --column;
  463.             } while (*mask != FIELDCHAR);
  464.             if (c == LEFT)
  465.             break;
  466.          case DEL:
  467.             movmem(buff+1, buff, strlen(buff));
  468.             *(buff+strlen(buff)) = ' ';
  469.             Wcursor(wnd, column, fld->frow);
  470.             dispfield(wnd, buff, mask);
  471.             break;
  472.          case RIGHT:
  473.             do    {
  474.                 column++;
  475.                 mask++;
  476.             } while (*mask && *mask != FIELDCHAR);
  477.             buff++;
  478.             break;
  479.          case INS:
  480.             insertmode ^= TRUE;
  481.             insertstatus();
  482.             break;
  483.          case '.':
  484.             if (fld->ftype == FLD_CURR)    {
  485.                 if (*mask++ && *buff == ' ')    {
  486.                     *buff++ = '0';
  487.                     if (*mask++ && *buff == ' ')
  488.                         *buff++ = '0';
  489.                     }
  490.                 rjust(fld->fbuff);
  491.                 Wcursor(wnd, fld->fcol, fld->frow);
  492.                 dispfield(wnd, fld->fbuff, fld->fmask);
  493.                 column = fld->fcol+strlen(fld->fmask)-2;
  494.                 mask = fld->fmask+strlen(fld->fmask)-2;
  495.                 buff = fld->fbuff+strlen(fld->fbuff)-2;
  496.                 break;
  497.             }
  498.          default:
  499.             if (fend(c))    {
  500.                 done = TRUE;
  501.                 break;
  502.             }
  503.             if (! testftype(fld,c) )
  504.                   break;
  505.             if (insertmode)    {
  506.                 movmem(buff, buff+1, strlen(buff)-1);
  507.                 dispfield(wnd, buff, mask);
  508.                 Wcursor(wnd, column, fld->frow);
  509.             }
  510.             *buff++ = c;
  511.             Wputch(wnd, c);
  512.                 do    {
  513.                     column++;
  514.                     mask++;
  515.                 } while (*mask && *mask != FIELDCHAR);
  516.             if (!*mask)
  517.             c = RIGHT;
  518.             break;
  519.         }   /* switch */
  520.         if (!*mask)
  521.             done = TRUE;
  522.         if (done)
  523.             break;
  524.  
  525.     }
  526.     if (c != ESC )     {
  527.         if (fld->ftype == FLD_CURR) {
  528.             if (*mask++ && *buff == ' ') {
  529.                 *buff++ = '0';
  530.                 if (*mask++ && *buff == ' ')
  531.                     *buff++ = '0';
  532.                 }
  533.             }
  534.     if (c < 0x80)
  535.            postprocess(fld);
  536.      Wcursor(wnd, fld->fcol, fld->frow);
  537.      dispfield(wnd, fld->fbuff, fld->fmask);
  538.     }  /* c != ESC */
  539.     return c;
  540. }
  541.  
  542. /* ------------------------------------------------------------------------ */
  543. /*                       test for a correct field type                      */
  544. /* ------------------------------------------------------------------------ */
  545. static int testftype(FIELD *fld, int c)
  546.  
  547. {
  548.    int s = 1;
  549.    int f = fld->ftype;
  550.  
  551.    if (c > 0x80)
  552.       return(1);
  553.    switch (f) {
  554.        case FLD_CURR   :
  555.        case FLD_DIGIT  :
  556.        case FLD_DATE   :
  557.        case FLD_INT    : if (! (s = isdigit(c) ))
  558.                 (fld->ferror)("Numeric char only");
  559.              break;
  560.        case FLD_ALNUM  : if (! (s = _isalnum(c) ))
  561.                 (fld->ferror)("Alpha numeric char only");
  562.              break;
  563.        case FLD_ALPHA  : if (! (s = _isalpha(c)))
  564.                 (fld->ferror)(" Alpha char only ");
  565.              break;
  566.        case FLD_ASCII  : if (! (s = isascii(c) ))
  567.                 (fld->ferror)(" Ascii char only ");
  568.              break;
  569.        case FLD_PRINT  : if (! (s = isprint(c) ))
  570.                 (fld->ferror)("Printable char only");
  571.              break;
  572.        case FLD_XDIGIT : if (! (s = isxdigit(c) ))
  573.                 (fld->ferror)(" Hexadecimal only ");
  574.              break;
  575.        }
  576.    return(s);
  577. }
  578.  
  579. /* ------------------------------------------------------------------------ */
  580. /*                     test for an ending keystroke                         */
  581. /* ------------------------------------------------------------------------ */
  582. static int esdefault(int c)
  583. {
  584.     switch (c)    {
  585.         case '\r':
  586.         case '\n':
  587.         case '\t':
  588.         case ESC:
  589.         case F1:
  590.         case F2:
  591.         case F3:
  592.         case F4:
  593.         case F5:
  594.         case F6:
  595.         case F7:
  596.         case F8:
  597.         case F9:
  598.         case F10:
  599.         case PGUP:
  600.         case PGDN:
  601.         case HOME:
  602.         case END:
  603.         case UP:
  604.         case DOWN:
  605.             return TRUE;
  606.         default:
  607.             return FALSE;
  608.     }
  609. }
  610.  
  611. /* ------------------------------------------------------------------------ */
  612. /*                          right justify, space fill                       */
  613. /* ------------------------------------------------------------------------ */
  614. static void rjust(char *s)
  615. {
  616.     int len;
  617.  
  618.     len = strlen(s);
  619.     while (*s == ' ' || *s == '0' && len)    {
  620.         len--;
  621.         *s++ = ' ';
  622.     }
  623.     if (len)
  624.         while (*(s+(len-1)) == ' ')    {
  625.             movmem(s, s+1, len-1);
  626.             *s = ' ';
  627.         }
  628. }
  629.  
  630. /* ------------------------------------------------------------------------ */
  631. /*                         right justify, zero fill                         */
  632. /* ------------------------------------------------------------------------ */
  633. static void rjustzf(char *s)
  634. {
  635.     int len;
  636.  
  637.     if (spaces(s))
  638.         return;
  639.     len = strlen(s);
  640.     while (*(s + len - 1) == ' ')    {
  641.         movmem(s, s + 1, len-1);
  642.         *s = '0';
  643.     }
  644. }
  645.  
  646. /* ------------------------------------------------------------------------ */
  647. /*                          test for spaces                                 */
  648. /* ------------------------------------------------------------------------ */
  649. static int spaces(char *c)
  650. {
  651.     while (*c == ' ')
  652.         c++;
  653.     return !*c;
  654. }
  655.  
  656. /* ------------------------------------------------------------------------ */
  657. /*                                                                          */
  658. /* ------------------------------------------------------------------------ */
  659. static void processhelp(FIELD *fld)
  660.  
  661. {
  662.    if (fld->fhelp == NULL)
  663.        return;
  664.    if ( ((fld->helptype & HELP_INITIAL) || (fld->helptype & HELP_ALWAYS))
  665.     && !(fld->helptype & HELP_DONE) )  {
  666.            (*(fld->fhelp))(fld->fbuff);
  667.            if (fld->helptype & HELP_INITIAL)
  668.               fld->helptype |= HELP_DONE;  /* set as done ! */
  669.         }
  670. }
  671.  
  672. /* ------------------------------------------------------------------------ */
  673. /*                default endstroke used for single input line              */
  674. /* ------------------------------------------------------------------------ */
  675. static int esinputline(int c)
  676. {
  677.     switch (c)    {
  678.     case '\r':
  679.     case '\n':
  680.     case ESC:
  681.         return TRUE;
  682.     default:
  683.         return FALSE;
  684.     }
  685. }
  686.  
  687. static WINDOW *defewnd = NULL;
  688. /* ------------------------------------------------------------------------ */
  689. /*                 set the default error function for fields                */
  690. /* ------------------------------------------------------------------------ */
  691. static void deferrorfunc(char *s)
  692.  
  693. {
  694.     if (s == NULL)   {
  695.           if (defewnd)  {
  696.             Wdelete(defewnd);
  697.             defewnd = NULL;
  698.           }
  699.     }
  700.     else  {
  701.        defewnd = Westablish(50, 22, 3, max(10, strlen(s)+2));
  702.        Wsetcolour(defewnd, WIN_ALL, RED, WHITE, BRIGHT);
  703.        Wsettitle(defewnd, "[Input Error]",JUST_C);
  704.        Wshow(defewnd);
  705.        Wprintf(defewnd, s);
  706.        vbeep(ERROR);
  707.    }
  708. }
  709.  
  710.